package br.com.tcc.dao;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.NoResultException;
import javax.persistence.Persistence;
import javax.persistence.Query;

import org.apache.log4j.Logger;

import br.com.tcc.model.ProdutoAndAnunciante;

public class ProdutoAndAnuncianteDAO {
	
	private EntityManagerFactory emf;
	Logger logger = Logger.getLogger(ProdutoAndAnuncianteDAO.class);
	
	public ProdutoAndAnuncianteDAO() {
		emf = Persistence.createEntityManagerFactory("persistencia");
	}

	public boolean adicionar(ProdutoAndAnunciante produtoAnunciante) {
		EntityManager em = emf.createEntityManager();
		boolean retorno = true;
		try {
			em.getTransaction().begin();
			em.merge(produtoAnunciante);
			em.getTransaction().commit();
		} catch (Exception e) {
			em.getTransaction().rollback();
			logger.warn("Erro no metodo  [ " + e.getMessage() + " ]");
			retorno = false;
			em.close();
		} finally {
			em.close();
		}
		return retorno;
	}

	/**
	 * Buscar os produto e ordenar pelo menor valor
	 * @param id
	 * @return
	 */
	
	public List<ProdutoAndAnunciante> buscarPrecoMaisCaroProduto(int id) {
		List<ProdutoAndAnunciante> retorno = null;
		EntityManager em = emf.createEntityManager();

		try {
			em.getTransaction().begin();
			Query q = em
					.createQuery("select p from ProdutoAndAnunciante p where p.produto.id= :idProduto order by p.produto.precoMaisCaro");
			q.setMaxResults(2);
			q.setParameter("idProduto", id);
			retorno = q.getResultList();
		} catch (NoResultException e) {
			System.out.println("sem registro");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			em.close();
		}
		return retorno;
	}
	
	public List<ProdutoAndAnunciante> listarProdutosAnunciante(int idAnunciante) {
		List<ProdutoAndAnunciante> retorno = null;
		EntityManager em = emf.createEntityManager();

		try {
			em.getTransaction().begin();
			Query q = em
					.createQuery("select p from ProdutoAndAnunciante p where p.anunciante.idAnunciante = :idAnunciante");
			q.setParameter("idAnunciante", idAnunciante);
			retorno = q.getResultList();
		} catch (NoResultException e) {
			logger.info("sem registro");
		} catch (Exception e) {
			logger.warn("Erro no metodo  [ " + e.getMessage() + " ]");
		} finally {
			em.close();
		}
		return retorno;
	}

	public List<ProdutoAndAnunciante> buscarProdutosParaAnunciantes(int idProduto, int idAnunciante1, int idAnunciante2, int idAnunciante3) {
		List<ProdutoAndAnunciante> retorno = null;
		EntityManager em = emf.createEntityManager();

		try {
			em.getTransaction().begin();
			Query q = em
					.createQuery("select p from ProdutoAndAnunciante p, Produto pr where" +
													" ( p.produto.id = :idProduto and  p.produto.id = pr.id) and" +
													" ( p.anunciante.idAnunciante = :idAnunciante1 or" +
													"   p.anunciante.idAnunciante = :idAnunciante2 or" +
													"   p.anunciante.idAnunciante = :idAnunciante3  )");
					
			q.setParameter("idProduto", idProduto);
			q.setParameter("idAnunciante1", idAnunciante1);
			q.setParameter("idAnunciante2", idAnunciante2);
			q.setParameter("idAnunciante3", idAnunciante3);
			retorno = q.getResultList();
		} catch (NoResultException e) {
			logger.info("sem registro");
		} catch (Exception e) {
			logger.warn("Erro no metodo  [ " + e.getMessage() + " ]");
		} finally {
			em.close();
		}
		return retorno;
	}

	public List<ProdutoAndAnunciante> buscarProdutosParaTresAnunciantes(int idAnunciante, int idAnunciante2, int idAnunciante3) {
		List<ProdutoAndAnunciante> retorno = null;
		EntityManager em = emf.createEntityManager();

		try {
			em.getTransaction().begin();
			Query q = em
					.createQuery("select p from ProdutoAndAnunciante p where p.anunciante.idAnunciante = :idAnunciante OR " +
							"p.anunciante.idAnunciante = :idAnunciante2 OR  p.anunciante.idAnunciante = :idAnunciante3 order by p.produto.nome");
			q.setParameter("idAnunciante", idAnunciante);
			q.setParameter("idAnunciante2", idAnunciante2);
			q.setParameter("idAnunciante3", idAnunciante3);
			retorno = q.getResultList();
		} catch (NoResultException e) {
			logger.info("sem registro");
		} catch (Exception e) {
			logger.warn("Erro no metodo  [ " + e.getMessage() + " ]");
		} finally {
			em.close();
		}
		return retorno;
	}
	
	/**
	 * Buscar os produto e ordenar pelo menor valor
	 * @param id
	 * @return
	 */
	
	public List<ProdutoAndAnunciante> buscarPrecoMaisBaratoProduto(int id) {
		List<ProdutoAndAnunciante> retorno = null;
		EntityManager em = emf.createEntityManager();

		try {
			em.getTransaction().begin();
			Query q = em
					.createQuery("select p from ProdutoAndAnunciante p where p.produto.id= :idProduto order by p.produto.precoMaisBarato");
			q.setMaxResults(2);
			q.setParameter("idProduto", id);
			retorno = q.getResultList();
		} catch (NoResultException e) {
			System.out.println("sem registro");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			em.close();
		}
		return retorno;
	}
	
	public boolean remover(int idProdutoAndAnunciante) {
		EntityManager em = emf.createEntityManager();
		boolean retorno = true;

		try {
			em.getTransaction().begin();
			Query q = em
					.createQuery("delete from ProdutoAndAnunciante p where p.idProdutoAndAnunciante = :idProdutoAndAnunciante");
			q.setParameter("idProdutoAndAnunciante", idProdutoAndAnunciante);
			q.executeUpdate();
			em.getTransaction().commit();
		} catch (NoResultException e) {
			logger.info("sem registro");
			retorno = false;
		} catch (Exception e) {
			logger.warn("Erro no metodo  [ " + e.getMessage() + " ]");
		} finally {
			em.close();
		}
		return retorno;
	}

	public ProdutoAndAnunciante buscarID(int idProdutoAndAnunciante){
		ProdutoAndAnunciante retorno = null;
		EntityManager em = emf.createEntityManager();
		try{
		   	em.getTransaction().begin();
		   	retorno = em.find(ProdutoAndAnunciante.class, idProdutoAndAnunciante);
		}catch (NoResultException e) {
			logger.info("sem registro");
		}catch (Exception e) {
			logger.warn("Erro no metodo  [ " + e.getMessage() + " ]");
		}finally{
			em.close();
		}
		return retorno;
	}

	public ProdutoAndAnunciante buscarProdutoAnunciante(int idAnunciante, int id) {
		ProdutoAndAnunciante retorno = null;
		EntityManager em = emf.createEntityManager();
		try {
			em.getTransaction().begin();
			Query q = em
					.createQuery("select p from ProdutoAndAnunciante p where p.produto.id=:id and p.anunciante.idAnunciante=:idAnunciante");
			q.setParameter("idAnunciante", idAnunciante);
			q.setParameter("id", id);
			retorno = (ProdutoAndAnunciante) q.getSingleResult();

		} catch (NoResultException e) {
			logger.info("sem registro");
		} catch (Exception e) {
			logger.warn("Erro no metodo  [ " + e.getMessage() + " ]");
		} finally {
			em.close();
		}

		return retorno;
	}

	public ProdutoAndAnunciante buscarCodigoBarra(String codigoBarra, int idAnunciante) {
		ProdutoAndAnunciante retorno = null;
		EntityManager em = emf.createEntityManager();
		try{
		   	em.getTransaction().begin();
		   	Query q = em.createQuery("select p from ProdutoAndAnunciante p where p.produto.codigoBarra=:codigoBarra and p.anunciante.idAnunciante =:idAnunciante");
		   	q.setParameter("codigoBarra", codigoBarra.trim());
		   	q.setParameter("idAnunciante", idAnunciante);
		   	retorno = (ProdutoAndAnunciante) q.getSingleResult();
	   	
		}catch (NoResultException e) {
			logger.info("sem registro");
		}catch (Exception e) {
			logger.warn("Erro no metodo  [ " + e.getMessage() + " ]");
		}finally{
			em.close();
		}
		
		return retorno;
	}
	
	public List<ProdutoAndAnunciante> listarProdutos(int idProduto) {
		List<ProdutoAndAnunciante> retorno = null;
		EntityManager em = emf.createEntityManager();

		try {
			em.getTransaction().begin();
			Query q = em
					.createQuery("select p from ProdutoAndAnunciante p where p.produto.id= :idProduto");
			q.setParameter("idProduto", idProduto);
			retorno = q.getResultList();
		} catch (NoResultException e) {
			logger.info("sem registro");
		} catch (Exception e) {
			logger.warn("Erro no metodo  [ " + e.getMessage() + " ]");
		} finally {
			em.close();
		}
		return retorno;
	}

}